<template>
	<a-modal
		:visible="visible"
		width="1000px"
		title="退租"
		centered
		destroyOnClose
		:maskClosable="false"
		@cancel="cancel"
		:footer="null"
		:bodyStyle="{padding: 0}">
		<a-form
			ref="formRef"
			:model="formData"
			:rules="formRules"
			layout="horizontal"
			class="flex-container-nomal"
			:labelCol="{style: {width: '90px'}}"
			style="height: 70vh"
			@finish="submit">
			<div class="flex1 auto-y">
				<a-space :size="12" direction="vertical" style="width: 100%">
					<div class="d-module-title">
						<b>房间信息</b>
					</div>
					<a-form-item label="" name="houseAddress">
						<a-input v-model:value="formData.houseAddress" disabled placeholder="请输入房源地址" />
					</a-form-item>

					<div class="d-module-title">
						<b>退租情况</b>
					</div>
					<a-row :gutter="10" style="height: 35px">
						<a-col>
							<a-form-item label="" name="backType">
								<a-radio-group
									v-model:value="formData.backType"
									button-style="solid"
									:disabled="isResubmit"
									@change="onNoramlChange">
									<a-radio-button :value="1">到期退</a-radio-button>
									<a-radio-button :value="2">违约退</a-radio-button>
								</a-radio-group>
							</a-form-item>
						</a-col>
						<a-col>
							<a-form-item label="退租日期" name="quiteDate" :rules="[{required: true, message: '请选择退租日期'}]">
								<a-date-picker
									v-model:value="formData.quiteDate"
									:value-format="DATE_FORMAT.DATE"
									:disabled="formData.backType === 1 || 3 === contractDetail.contractStatus || isResubmit"
									:disabled-date="disabledDate"
									@change="incomeList()" />
							</a-form-item>
						</a-col>
						<a-col>
							<a-form-item label="退款账号" name="paymentAccount">
								<a-input-group compact>
									<a-form-item-rest>
										<a-select
											v-model:value="formData.paymentAccountType"
											:options="paymentAccountList"
											placeholder="请选择类型"
											style="width: 100px" />
									</a-form-item-rest>
									<a-input style="width: 180px" v-model:value="formData.paymentAccount" placeholder="请输入账号" />
								</a-input-group>
							</a-form-item>
						</a-col>

						<a-col v-if="!isResubmit">
							<a-button type="primary" @click="delivery.deliveryVisible = true" style="width: 160px">
								<check-outlined v-if="'{}' !== JSON.stringify(delivery.info) && delivery.info" />
								<plus-outlined v-else />
								确认退房交割单
							</a-button>
						</a-col>
					</a-row>

					<!-- 银联需要填写该信息 -->
					<a-row :gutter="30">
						<a-col v-if="[1].includes(formData.paymentAccountType)">
							<a-form-item :labelCol="{style: {width: '70px'}}" labelAlign="left" label="银行行号" name="bankNumber">
								<a-input
									:style="{
										width: [1].includes(formData.paymentAccountType) && 2 === formData.backType ? '230px' : '325px'
									}"
									v-model:value="formData.bankNumber"
									placeholder="请输入银行行号" />
							</a-form-item>
						</a-col>
						<a-col v-if="[1].includes(formData.paymentAccountType)">
							<a-form-item :labelCol="{style: {width: '70px'}}" labelAlign="left" label="开户银行" name="bankName">
								<a-input
									:style="{
										width: [1].includes(formData.paymentAccountType) && 2 === formData.backType ? '230px' : '279px'
									}"
									v-model:value="formData.bankName"
									placeholder="请输入开户银行" />
							</a-form-item>
						</a-col>
						<a-col v-if="2 === formData.backType && !props?.isResubmit">
							<a-form-item :labelCol="{style: {width: '85px'}}" labelAlign="left" label="退租发起方" name="bankName">
								<a-select
									:style="{width: [1].includes(formData.paymentAccountType) ? '200px' : '312px'}"
									placeholder="请选择退租发起方"
									ref="select"
									v-model:value="formData.backInitiator"
									@change="incomeList">
									<a-select-option :value="1">业主</a-select-option>
									<a-select-option :value="2">公寓</a-select-option>
								</a-select>
							</a-form-item>
						</a-col>
					</a-row>

					<div class="d-module-title">
						<b>退租明细</b>
					</div>
					<vxe-grid v-bind="gridOptions" :data="tableData" align="center">
						<template #feeDirection="{row}">
							<svg-icon
								:icon-class="`finance-${1 === row.feeDirection ? 'in' : 'out'}`"
								style="width: 22px; height: 14px; margin-right: 6px" />
							<span :class="(1 === row.feeDirection ? 'processing' : 'error') + '-color'">
								{{ 1 === row.feeDirection ? '收' : '支' }}
							</span>
						</template>
						<template #feeSubject="{row}">
							<a-select
								v-model:value="row.feeSubjectId"
								:class="{error: !row.feeSubjectId}"
								:disabled="row.disabled"
								:options="feeSubject"
								show-search
								option-filter-prop="name"
								:field-names="{label: 'name', value: 'id', options: 'metaList'}"
								placeholder="请选择费用科目"
								style="width: 100%; text-align: left" />
						</template>
						<template #amount="{row}">
							<a-input-number
								v-model:value="row.amount"
								:class="{error: row.amount === null || row.amount < 0}"
								:min="0"
								:precision="2"
								placeholder="请输入金额"
								style="width: 100%" />
						</template>
						<template #cycle="{row}">
							<a-range-picker
								:class="{error: !row.timeInfo.length}"
								style="width: 100%"
								v-model:value="row.timeInfo"
								:value-format="DATE_FORMAT.DATE" />
						</template>
						<template #action="{row, rowIndex}">
							<a-button type="link" size="small" danger @click="tableData.splice(rowIndex, 1)">删除</a-button>
						</template>
						<template #bottom>
							<vxe-toolbar perfect>
								<template #buttons>
									<span>费用总计：{{ totalMoney.toLocaleString() }}元</span>
								</template>
								<template #tools>
									<a-space>
										<a class="processing" @click="addBill(1)">
											<plus-square-outlined />
											添加收款项
										</a>
										<a class="error" @click="addBill(2)">
											<minus-square-outlined />
											添加付款项
										</a>
									</a-space>
								</template>
							</vxe-toolbar>
						</template>
					</vxe-grid>

					<div class="d-module-title">
						<b>备注</b>
					</div>
					<a-form-item label="" name="quiteComment">
						<a-textarea v-model:value="formData.quiteComment" placeholder="请输入备注" :rows="4" show-count :maxlength="200" />
					</a-form-item>
				</a-space>
			</div>
			<div class="a-modal-dialog-footer">
				<a-space :size="12">
					<a-button @click="cancel" :loading="loading" :disabled="loading">取消</a-button>
					<a-button :loading="loading" :disabled="loading" type="primary" html-type="submit">确定</a-button>
				</a-space>
			</div>
		</a-form>

		<lease-off-settlement
			v-model:visible="delivery.deliveryVisible"
			:id="props.contractId"
			:houseId="formData.houseId"
			:is-resubmit="isResubmit"
			@success="SetDelivery"
			:type="3"
			:getDelivery="XEUtils.clone(delivery.info, true)"></lease-off-settlement>
	</a-modal>
</template>

<script lang="ts" setup>
	import {computed, reactive, ref, watch} from 'vue'
	import LeaseOffSettlement from '@/components/contract/tenant/lease-off-settlements.vue'
	import {
		getOwnerContractDetail,
		ownerBreakAbnormalList,
		ownerBreakNormalList,
		getHouseDeliveryGetNoe,
		ownerBreakNormal,
		ownerBreakAbnormal
	} from '@/api/contract'
	import DATE_FORMAT, {nowDate} from 'yuxin-base/src/utils/date'
	import settingApi from 'yuxin-base/src/api/setting-api'
	import {retreatRentFormRow, contractDetailRow} from './interface'
	import {DIC_LABEL_MAP} from 'yuxin-base/src/constant'
	import {VxeGridProps} from 'vxe-table'
	import {FormInstance, message} from 'ant-design-vue'
	import {MinusSquareOutlined, PlusOutlined, PlusSquareOutlined, CheckOutlined} from '@ant-design/icons-vue'
	import {paymentAccountList} from '@/utils'
	import dayjs, {Dayjs} from 'dayjs'
	import XEUtils from 'xe-utils'

	const props = defineProps<{
		visible: boolean
		contractId: string
		quiteDate?: string
		isResubmit?: boolean
	}>()
	const emits = defineEmits(['update:visible', 'success'])
	/** contractStatus 3 即将搬入 4 已到期 */
	const contractDetail = ref<contractDetailRow>({id: '', signType: -1})
	const formRef = ref<FormInstance>()
	const formRules = {}
	/** 表单 */
	const formData = reactive<retreatRentFormRow>({
		backType: 2,
		houseAddress: '',
		houseId: '',
		paymentAccount: '',
		paymentAccountType: 1,
		bankNumber: null,
		bankName: null,
		quiteComment: '',
		quiteDate: '',
		backInitiator: 2
	})
	/** 退租交割单 */
	const delivery = reactive<any>({
		info: {},
		deliveryVisible: false,
		deliveryId: ''
	})
	/** 费用科目列表 */
	const feeSubject = ref<any>([])
	const loading = ref(false)
	const tableData = ref<any>([])

	/** 获取收支列表 */
	const incomeList = async (data = []) => {
		const params: any = {
			contractId: props.contractId,
			quiteDate: formData.quiteDate,
			meterReadRecordDtos: data,
			backInitiator: null
		}
		/** 如果是违约退 则要传入违约承担方字段进行查询账单 */
		if (2 === formData.backType) params.backInitiator = formData.backInitiator
		loading.value = true
		const res = await (1 === formData.backType ? ownerBreakNormalList(params) : ownerBreakAbnormalList(params)).finally(() => {
			loading.value = false
		})
		billProcessing(res.data)
	}

	/** 处理收支账单 */
	const billProcessing = data => {
		data.forEach((item: any) => {
			item.disabled = true
			item.timeInfo = [item.beginDate, item.endDate]
			// 表单校验
			item.checkFeeSubjectId = true
			item.checkAmount = true
			item.checkTimeInfo = true
			if (!item.amount) {
				item.amount = 0
			}
		})
		tableData.value = data
	}

	// 非合同即将搬入状态只能选择合同开始日期到当天日期
	const disabledDate = (current: Dayjs) => {
		return (
			dayjs(current).format(DATE_FORMAT.DATE) <
			dayjs(contractDetail.value.beginTime ? contractDetail.value.beginTime : nowDate()).format(DATE_FORMAT.DATE) ||
			dayjs(current).format(DATE_FORMAT.DATE) > dayjs().format(DATE_FORMAT.DATE)
		)
	}

	/** 获取业主合同详情 */
	const getData = () => {
		getOwnerContractDetail(props.contractId).then(({data}) => {
			contractDetail.value = data
			formData.houseAddress = data.house.address
			formData.houseId = data.houseId
			if (dayjs().isBefore(dayjs(data.beginTime))) {
				formData.quiteDate =
					3 === contractDetail.value.contractStatus
						? dayjs().format(DATE_FORMAT.DATE)
						: dayjs(data.beginTime).format(DATE_FORMAT.DATE)
			} else {
				formData.quiteDate = nowDate()
			}
			/* 如果是已到期就是正常退 */
			if (5 === data.contractStatus) {
				formData.backType = 1
				formData.quiteDate = data.endTime
			}
			if (props?.isResubmit) {
				formData.quiteDate = data?.quiteDate
				formData.quiteComment = data?.quiteComment
			}

			/** 获取退房交割单 */
			getDelivery()

			/** 初始化账单 */
			if (props?.isResubmit) {
				let billInfos = (data.billInfos || []).filter(o => o.num == 999) || [],
					bills = billInfos.length ? (billInfos[0]?.bills || []).filter(k => k.billType == 3) : [],
					finances = bills.length ? bills[0].finances : []
				billProcessing(finances)
			} else {
				incomeList()
			}
		})
		// 获取费用科目列表
		// 82308字典修改
		settingApi.getDicListByLabel(DIC_LABEL_MAP.FEESUBJECT, {isUse: null}).then(({data}) => {
			data.forEach((item: any) => {
				item.selectable = false
			})
			feeSubject.value = data
		})
	}
	const SetDelivery = (data: any) => {
		delivery.info = data
		// XEUtils.clone(delivery.info, true)
		// isCheckDelivery.value = true
		// // 设备费用存在 刷新账单
		// if (delivery.info?.meterReadRecordDtos && delivery.info.meterReadRecordDtos.length) {
		// 	Modal.warning({
		// 		title: '提示',
		// 		content: '账单已更新，还请重新核对账单明细!'
		// 	})
		// 	incomeList(delivery.info.meterReadRecordDtos)
		// } else {
		// 	billListInfo()
		// }
	}
	/**
	 * @params 1 添加收款账单 2 添加付款账单
	 * 添加收付款账单
	 */
	const addBill = (type: number | string) => {
		let obj = {
			// 收支金额
			amount: null,
			timeInfo: [],
			beginDate: '',
			// 费用类型
			costType: 0,
			endDate: '',
			// 费用方向【1收入2支出】
			feeDirection: type,
			// 费用科目id【字典】
			feeSubjectId: null,
			// 费用科目名称
			feeSubjectName: '',
			// 表单校验
			checkFeeSubjectId: true,
			checkAmount: true,
			checkTimeInfo: true,
			notOccurredMoney: null
		}
		tableData.value.push(obj)
	}

	/** 合计 */
	const totalMoney = computed(() => {
		let total = 0
		for (let item of tableData.value) {
			if (item.feeDirection === 1) {
				total += item.amount * 1
			} else {
				total -= item.amount * 1
			}
		}
		return total.toFixed(2)
	})

	/** 重置表单 */
	const resetForm = () => {
		formData.houseId = ''
		formData.paymentAccountType = 1
		tableData.value = []
		delivery.info = {}
		formRef.value?.resetFields()
	}

	const cancel = () => {
		emits('update:visible', false)
		resetForm()
	}

	const gridOptions = reactive<VxeGridProps>({
		size: 'small',
		maxHeight: 400,
		rowConfig: {
			isHover: true,
			isCurrent: true
		},
		columns: [
			{
				title: '收支类型',
				field: 'feeDirection',
				width: 100,
				align: 'center',
				slots: {
					default: 'feeDirection'
				}
			},
			{
				title: '费用科目',
				field: 'feeSubjectId',
				minWidth: 200,
				align: 'center',
				slots: {
					default: 'feeSubject'
				}
			},
			{
				title: '金额(元)',
				field: 'amount',
				minWidth: 150,
				align: 'center',
				slots: {
					default: 'amount'
				}
			},
			{
				title: '账单周期',
				field: 'cycle',
				align: 'center',
				minWidth: 300,
				slots: {
					default: 'cycle'
				}
			},
			{
				title: '操作',
				align: 'center',
				width: 100,
				slots: {
					default: 'action'
				}
			}
		]
	})

	const dealDelivery = (contractId: string) => {
		let newDelivery = JSON.parse(JSON.stringify(delivery.info))
		let meterReadRecordDtos = []
		if (newDelivery && newDelivery.constructor === Object && newDelivery.hasOwnProperty('meterReadRecordDtos')) {
			meterReadRecordDtos =
				(newDelivery.meterReadRecordDtos || []).map((e: any) => {
					return {
						deviceType: e.deviceType,
						deviceId: e.deviceId,
						read: e.amount
					}
				}) || []
			delete newDelivery['meterReadRecordDtos']
		}
		let energyDictArr = []
		if (newDelivery && newDelivery.constructor === Object && newDelivery.hasOwnProperty('energyDictArr')) {
			energyDictArr =
				(newDelivery.energyDictArr || []).map((e: any) => {
					return {
						deviceType: e.deviceType,
						deviceId: e.deviceId,
						read: e.lastRead
					}
				}) || []
			delete newDelivery['energyDictArr']
		}
		let meters = [...meterReadRecordDtos, ...energyDictArr]
		return {
			/** 交割类型-1:签约 2:退房 */
			deliveryType: 2,
			/** 合同类型-1 个人 2 企业 3 业主 */
			compactType: 3,
			houseId: formData.houseId,
			compactId: contractId,
			meters,
			...newDelivery
		}
	}

	/** 校验值是否填写完成 */
	const amountHandler = () => {
		let checkFee = false
		for (let item of tableData.value) {
			/** 校验费用科目 */
			item.checkFeeSubjectId = !!item.feeSubjectId
			if (!item.feeSubjectId) {
				checkFee = true
			}
			/** 校验金额 */
			item.checkAmount = item.amount * 1 >= 0
			if (!item.checkAmount) {
				checkFee = true
			}
			/** 校验时间周期 */
			if (0 === item.timeInfo.length) {
				item.checkTimeInfo = false
				checkFee = true
			} else {
				item.beginDate = item.timeInfo[0]
				item.endDate = item.timeInfo[1]
				item.checkTimeInfo = true
			}
		}
		return checkFee
	}

	/** 提交 */
	const submit = async () => {
		if (amountHandler()) return
		if (1 === formData.backType && dayjs().isBefore(formData.quiteDate, 'day')) {
			return message.error('合同未到期，无法办理到期退')
		}
		const {contractStatus, signType} = contractDetail.value
		if (1 === contractStatus && 2 === signType) return message.error('原合同未到期，不允许操作退租，请作废')
		const params: any = {
			applyId: contractDetail.value.id,
			backType: formData.backType,
			bankName: formData.bankName,
			bankNumber: formData.bankNumber,
			paymentAccount: formData.paymentAccount,
			paymentAccountType: formData.paymentAccountType,
			contractId: contractDetail.value.id,
			quiteComment: formData.quiteComment,
			quiteDate: formData.quiteDate,
			finances: tableData.value,
			deliveryAddForm: dealDelivery(contractDetail.value.id),
			backInitiator: null
		}
		if (params.deliveryAddForm?.id) delete params.deliveryAddForm.id
		//重新提交物业交割单不需要保存
		if (props.isResubmit && params['deliveryAddForm']) delete params['deliveryAddForm']
		/** 如果是违约退 则要传入违约承担方字段进行退租 */
		if (2 === formData.backType) params.backInitiator = formData.backInitiator
		const requestApi = 1 === formData.backType ? ownerBreakNormal : ownerBreakAbnormal

		console.log(params, 'params')

		// 82308字典修改 保存判断选择的字典是否被禁用
		let typesList: any = []
		let list: any = []
		typesList = await settingApi.getDicListByLabel(DIC_LABEL_MAP['FEESUBJECT'], {isUse: 1})
		typesList.data.forEach((e: any) => {
			list.push(...e.metaList)
		})
		list.forEach((e: any) => {
			params.finances.forEach((o: any) => {
				if (e.id === o.feeSubjectId) {
					o.active = true
				}
			})
		})
		if (!params.finances?.every((e: any) => e?.active == true)) return message.error('选项已禁用，请选择其他选项！')

		loading.value = true
		requestApi(params)
			.then(res => {
				cancel()
				emits('success')
			})
			.finally(() => {
				loading.value = false
			})
	}

	// 获取退房交割单
	const getDelivery = () => {
		let params = {
			id: props.contractId,
			type: 2
		}
		getHouseDeliveryGetNoe(params).then((res: any) => {
			delivery.info = res.data || {}
			if (res.data) {
				delivery.deliveryId = res?.data.id
			}
		})
	}

	const onNoramlChange = () => {
		if (formData.backType === 1) {
			formData.quiteDate = contractDetail.value?.endTime || nowDate()
		} else {
			formData.quiteDate = nowDate()
		}
		incomeList()
	}

	watch(
		() => props.visible,
		(newVal: boolean) => {
			if (newVal) {
				getData()
			}
		}
	)
</script>

<style lang="less" scoped>
	:deep(.vxe-table--footer-wrapper.body--wrapper) {
		overflow: hidden;
	}
</style>
